package com.threeti.mecool.core.infrastructure.persistence.plan;

import com.threeti.mecool.core.domain.model.plan.pojo.Plan;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Date;

public class PlanSpecs {
    public static Specification<Plan> statusIs(final String status) {
        return new Specification<Plan>() {
            @Override
            public Predicate toPredicate(Root<Plan> planRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.equal(planRoot.<String>get("status"), status);
            }
        };
    }

    public static Specification<Plan> nameLike(final String name) {
        return new Specification<Plan>() {
            @Override
            public Predicate toPredicate(Root<Plan> planRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.like(planRoot.<String>get("name"), "%" + name + "%");
            }
        };
    }

    public static Specification<Plan> planDateIs(final Date planDate) {
        return new Specification<Plan>() {
            @Override
            public Predicate toPredicate(Root<Plan> planRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.equal(planRoot.<Date>get("planDate"), planDate);
            }
        };
    }

    public static Specification<Plan> userLoginNameIs(final String userLoginName) {
        return new Specification<Plan>() {
            @Override
            public Predicate toPredicate(Root<Plan> planRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.equal(planRoot.<String>get("userLoginName"), userLoginName);
            }
        };
    }

    public static Specification<Plan> planDateGreaterOrEqualsThan(final Date planDate) {
        return new Specification<Plan>() {
            @Override
            public Predicate toPredicate(Root<Plan> planRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.greaterThanOrEqualTo(planRoot.<Date>get("planDate"), planDate);
            }
        };
    }

    public static Specification<Plan> planDateGreaterThan(final Date planDate) {
        return new Specification<Plan>() {
            @Override
            public Predicate toPredicate(Root<Plan> planRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.greaterThan(planRoot.<Date>get("planDate"), planDate);
            }
        };
    }

    public static Specification<Plan> assignedByIs(final String assignedBy) {
        return new Specification<Plan>() {
            @Override
            public Predicate toPredicate(Root<Plan> planRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.equal(planRoot.<String>get("assignedBy"), assignedBy);
            }
        };
    }

    public static Specification<Plan> typeIs(final String type) {
        return new Specification<Plan>() {
            @Override
            public Predicate toPredicate(Root<Plan> planRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.equal(planRoot.<String>get("type"), type);
            }
        };
    }

    public static Specification<Plan> confirmedByIs(final String confirmedBy) {
        return new Specification<Plan>() {
            @Override
            public Predicate toPredicate(Root<Plan> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.equal(root.<String>get("confirmedBy"), confirmedBy);
            }
        };
    }

    public static Specification<Plan> typeIsNull() {
        return new Specification<Plan>() {
            @Override
            public Predicate toPredicate(Root<Plan> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.isNull(root.get("type"));
            }
        };
    }
}
